import axios from "axios";
import * as crypto from "node:crypto";
import path from "node:path";
import fs from "node:fs";
import yaml from "js-yaml";
import { get, set } from "lodash-es"
import { chalk, getArgs } from "./util.js";

// 0) 全局参数
const FROM = 'zh-CHS'
const TO = 'my'
const ZH_CN_DIR = path.resolve("./", "lang", "zh_CN");
const TO_DIR = path.resolve("./", "lang", "my_MM");
const TRANSLATE_FILE = path.resolve("./", "translate/");
const UNHANDLE_KEY = ["oneLineMeansPushingAnAccountLinkTips", "oneLineMeansPushingAnAccountLinkTips1"]

// 1) 翻译函数
const translate = async (querys: string[]) => {
  const appKey = "47914f736192fb7c";
  const key = "8xvcmYnXddtFX2uU6Zjurd77p9NfJ8IP";
  const salt = new Date().getTime();
  const curtime = Math.round(new Date().getTime() / 1000);
  const from = FROM;
  const to = TO;
  const str = appKey + truncate(querys.join("")) + salt + curtime + key;
  const sign = generateSHA256Hash(str);
  const url = "https://openapi.youdao.com/v2/api";
  const parmas = `?q=${querys.join(
    "&q="
  )}&appKey=${appKey}&salt=${salt}&from=${from}&to=${to}&sign=${sign}&signType=v3&curtime=${curtime}`;
  const res = await axios.get(url + parmas);
  return res.data?.translateResults || [];
};
const truncate = (q: string) => {
  var len = q.length;
  if (len <= 20) return q;
  return q.substring(0, 10) + len + q.substring(len - 10, len);
};
const generateSHA256Hash = (str: string) => {
  // 创建一个 hash 实例
  const hash = crypto.createHash("sha256");
  // 更新 hash 实例的内容
  hash.update(str);
  // 获取十六进制格式的摘要
  const sign = hash.digest("hex").toString();
  return sign;
};

const readYamlFile = (filePath: string) => yaml.load(fs.readFileSync(filePath, "utf8"));
const writeYamlFile = (filePath: string, obj: Record<string, any>) => fs.writeFileSync(filePath, yaml.dump(obj), { encoding: "utf8", flag: 'w' });
const containsEnglish = (text: string) => /[a-zA-Z]+/.test(text)

// 3) 查询携带翻译的英文
const queryEnglish = (jsonObj: Record<string, any>, modifyTxt: string[] = [], lasyKey: string = '') => {
  Object.entries(jsonObj).forEach(([key, value]) => {
    if (UNHANDLE_KEY.includes(key)) return
    if (typeof value === 'object') queryEnglish(value, modifyTxt, `${lasyKey}${key}.`)
    else if (value && containsEnglish(value)) {
      modifyTxt.push(`${lasyKey}${key}`)
    }
  })
}
const translateTxt = async (filePath: string, zhJsonObj: Record<string, any>, originJsonObj: Record<string, any>, modifyTxt: string[]) => {
  try {
    // 1 获取全部需要翻译的 value
    const values = modifyTxt.map(key => get(zhJsonObj, key))
    console.log(chalk.blue(`翻译文件: ${filePath}, 数量: ${modifyTxt.length};`));
    // 2 进行翻译
    const res = await translate(values)
    console.log(chalk.green(`翻译完成: ${filePath}!`));
    // 3 替换
    res.forEach((item: any, index: number) => set(originJsonObj, modifyTxt[index], item.translation))
    // 4 写入文件
    writeYamlFile(filePath, originJsonObj)
  } catch (error) {

  }
}
const generateTranslateFile = (filePath: string, zhJsonObj: Record<string, any>, originJsonObj: Record<string, any>, modifyTxt: string[]) => {
  let str = `${filePath}\n`
  modifyTxt.forEach(key => str += `${get(zhJsonObj, key)}\n`)
  fs.writeFileSync(path.join(TRANSLATE_FILE, path.basename(filePath)), str, { encoding: "utf8", flag: 'w' })
}
const translateTxt2 = async (filePath: string, zhJsonObj: Record<string, any>, originJsonObj: Record<string, any>, modifyTxt: string[]) => {
  try {
    // 1 获取映射列表
    const mapArr = getTranslateArr()[filePath]
    // 2 校验
    if (mapArr.length !== modifyTxt.length) {
      console.log(mapArr.length);
      console.log(modifyTxt.length);
      throw new Error(`翻译文件: ${filePath}, 数量不一致!${mapArr.length} : ${modifyTxt.length}`)
    }
    // 3 替换, 进行翻译
    mapArr.forEach((item: any, index: number) => set(originJsonObj, modifyTxt[index], item))
    // 4 写入文件
    writeYamlFile(filePath, originJsonObj)
    console.log(chalk.green(`翻译完成: ${filePath}!`));
  } catch (error) {
    console.log(chalk.red(`翻译失败: ${filePath}!`));
  }
}
const getTranslateArr = () => {
  const translateArr = fs.readFileSync(TRANSLATE_FILE, { encoding: "utf8" }).split("\n")
  let curItem = ""
  const fileMap: any = {}
  translateArr.forEach((item: string, index: number) => {
    if (index === translateArr.length - 1) return
    if (item.includes(`lang\\my_MM\\`)) {
      fileMap[item] = []
      curItem = item
    }
    else {
      fileMap[curItem] && fileMap[curItem].push(item)
    }
  })
  return fileMap
}
// 只翻译文件夹内部
const translateTxt3 = async (filePath: string, zhJsonObj: Record<string, any>, originJsonObj: Record<string, any>, modifyTxt: string[]) => {
  try {
    // 1 获取映射列表
    const mapArr = fs.readFileSync(path.join(TRANSLATE_FILE, path.basename(filePath)), { encoding: "utf8" }).split("\n")
    mapArr.shift()
    mapArr.pop()
    // 2 校验
    if (mapArr.length !== modifyTxt.length) {
      console.log(mapArr.length);
      console.log(modifyTxt.length);
      throw new Error(`翻译文件: ${filePath}, 数量不一致!${mapArr.length} : ${modifyTxt.length}`)
    }
    // 3 替换, 进行翻译
    mapArr.forEach((item: any, index: number) => set(originJsonObj, modifyTxt[index], item))
    // 4 写入文件
    writeYamlFile(filePath, originJsonObj)
    console.log(chalk.green(`翻译完成: ${filePath}!`));
  } catch (error) {
    console.log(chalk.red(`翻译失败: ${filePath}!`));
  }
}

// 4) 主函数
async function main() {
  const args = getArgs()
  const command = args.shift()
  if (!command) {
    console.log(chalk.red("请输入指令"));
    return
  }
  try {
    command === '-g' && fs.rmSync(TRANSLATE_FILE)
  } catch (error) {

  }
  try {
    // 0 执行存储列表
    const execList: ((i: number) => Promise<void>)[] = []
    // 1 获取文件夹
    const fromDirs = await fs.readdirSync(ZH_CN_DIR);
    const toDirs = await fs.readdirSync(TO_DIR);
    const fromFiles = fromDirs.map(ymlFileName => path.join(ZH_CN_DIR, ymlFileName))
    const toFiles = toDirs.map(ymlFileName => path.join(TO_DIR, ymlFileName))
    const execFiles = args[0] === "*" ? ['*'] : args.map(val => `${val}.yaml`)
    // 2 遍历翻译文件
    toFiles.forEach((ymlPath, ymlIndex) => {
      // 校验
      if (args[0] !== "*" && !execFiles.some(val => ymlPath.includes(val))) return
      // 3 转化成 json 对象
      const jsonObj = readYamlFile(ymlPath) || {}
      const zhJsonObj = readYamlFile(fromFiles[ymlIndex]) || {}
      const modifyTxt: string[] = []
      // 4 遍历 value 值，找出携带英文的翻译
      queryEnglish(jsonObj, modifyTxt)
      // 5 生成待翻译文件
      command === '-g' && generateTranslateFile(ymlPath, zhJsonObj, jsonObj, modifyTxt)
      // 5 插入执行函数
      execList.push(async (currentIndex: number) => {
        console.log(chalk.blue(`正在执行第${currentIndex + 1}个文件`));
        await translateTxt3(ymlPath, zhJsonObj, jsonObj, modifyTxt)
        return Promise.resolve()
      })
    })
    // 6 执行翻译
    command === '-c' && execList.reduce(async (acc, func, currentIndex) => {
      try {
        await acc
        return func(currentIndex)
      } catch (error) {
        console.log(chalk.red(`执行第${currentIndex + 1}个文件失败`));
      }
    }, Promise.resolve())
  } catch (error) {
    console.error("处理过程中发生错误:", error);
  }
}

main();
